﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace XmlToPdf
{
    public class AesEncryptor
    {
        private AesManaged _aesManager;
        private string _encryptedFileExtension = ".aes";

        /// <summary>
        /// aes算法加密类
        /// 
        /// </summary>
        /// <param name="key">密钥(长度为16 byte)</param>
        /// <param name="iv">V向量(长度为16 byte)</param>
        public AesEncryptor(byte[] key, byte[] iv)
        {
            _aesManager = new AesManaged();
            int keySize = _aesManager.CreateEncryptor().InputBlockSize;
            _aesManager.Key = key;
            _aesManager.IV = iv;
        }

        ///
        public byte[] EncryptString(byte[] originalStr)
        {
            try
            {
                
                byte[] encrptStr =_aesManager.CreateEncryptor().TransformFinalBlock(originalStr, 0, originalStr.GetLength(0));
                return encrptStr;
                
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public byte[] DecryptString(byte[] originalStr)
        {
            try
            {
                byte[] decrptStr = _aesManager.CreateDecryptor().TransformFinalBlock(originalStr, 0, originalStr.GetLength(0));
                return decrptStr;

            }
            catch (Exception e)
            {
                throw e;
            }
        }


        /// <summary>
        /// Encrypts a file to a directory
        /// </summary>
        /// <param name="file">File to encrypt</param>
        /// <param name="encryptedDirectory">Directory to send the encrypted file to</param>
        public void EncryptFile(FileInfo file, DirectoryInfo encryptedDirectory)
        {
            string newFilePath = Path.Combine(
                encryptedDirectory.FullName,
                file.Name + _encryptedFileExtension);

            try
            {
                using (var encryptedStream = new CryptoStream(File.Create(newFilePath),_aesManager.CreateEncryptor(),CryptoStreamMode.Write))
                using (var originalFileStream = file.OpenRead())
                {
                    byte[] buffer = new byte[10000];
                    int bufferSize = originalFileStream.Read(buffer, 0, buffer.Length);
                    while (bufferSize > 0)
                    {
                        encryptedStream.Write(buffer, 0, bufferSize);
                        bufferSize = originalFileStream.Read(buffer, 0, buffer.Length);
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }


        /// <summary>
        /// Decrypts a file to a directory
        /// </summary>
        /// <param name="file">File to decrypt</param>
        /// <param name="decryptedDirectory">Directory to send the decrypted file to</param>
        public void DecryptFile(FileInfo file, DirectoryInfo decryptedDirectory)
        {
            string decryptedFilePath = (file.Name.EndsWith(_encryptedFileExtension)) ?
                Path.Combine(
                    decryptedDirectory.FullName,
                    file.Name.Substring(0, file.Name.LastIndexOf(_encryptedFileExtension))) :
                Path.Combine(
                    decryptedDirectory.FullName,
                    file.Name);

            try
            {
                using (var decryptStream = new CryptoStream(file.OpenRead(), _aesManager.CreateDecryptor(), CryptoStreamMode.Read))
                using (var decryptedFileStream = File.Create(decryptedFilePath))
                {
                    byte[] buffer = new byte[10000];
                    int bufferSize = decryptStream.Read(buffer, 0, buffer.Length);
                    while (bufferSize > 0)
                    {
                        decryptedFileStream.Write(buffer, 0, bufferSize);
                        bufferSize = decryptStream.Read(buffer, 0, buffer.Length);
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }


    }
}
